package com.andkrup.web.components {
	import com.andkrup.web.navigation.NavigationManager;
	
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	
	import com.andkrup.web.navigation.INavigationManager;	
	import com.andkrup.events.NavigateEvent;	
	import com.andkrup.web.components.IComponent;
	import com.andkrup.web.navigation.Navigator;
	import com.andkrup.web.navigation.NavigatorItem;
	
	/**
	 * @author Andkrup
	 * 
	 * A Basic Menu-Component.
	 * As Navigator it listens to events from its menu-items and delegates the
	 * concrete job of swapping views to its pilot
	 */
	public class NavComponent extends Sprite implements IComponent, Navigator {
		protected var components:Array;
		protected var navItems : Array;
		private var navigationManager : INavigationManager;
		
		public function get displayObject():DisplayObject {
			return this;
		}
		
		public function get commandpilot():INavigationManager{
			return navigationManager;
		}
		public function set commandpilot(value:INavigationManager):void{
			navigationManager = value;
		}

		public function NavComponent(pilot : INavigationManager = null) {
			if(null!=pilot){
				navigationManager = pilot;
			}
			else{
				navigationManager = NavigationManager.instance;
			}
			components = [];
			navItems = [];
		}
		
		public function hasComponent(component : IComponent) : Boolean {
			var l:int = components.length;
			for(var i:int = 0; i < l;i++){
				if(components[i]==component) return true;
			}
			return false;
		}
		
		public function addComponent(component : IComponent) : void {
			if(hasComponent(component)) return;
			components.push(component);
			if(component is NavigatorItem) addNavigatorItem(component as NavigatorItem);
			addChild(component as DisplayObject);
		}
		
		public function removeComponent(component : IComponent) : void {
			var l:int = components.length;
			for(var i:int = 0; i < l;i++){
				if(components[i]==component){
					components.slice(i,1);
					if(component is NavigatorItem) removeNavigatorItem(component as NavigatorItem);
					removeChild(component as DisplayObject);
				}
			}
		}
		
		public function init(data : *) : void {
			throw new Error("abstract method - please override");
		}
		
		public function kill() : void {
			throw new Error("abstract method - please override");
		}
		
		public function onNavigationStateChange(ne : NavigateEvent) : void {
			navigationManager.handleNavigation(ne.command);
		}
		
		public function addNavigatorItem(item : NavigatorItem) : void {
			if(hasNavigatorItem(item)){
				return;
			}
			item.addEventListener(NavigateEvent.NAVIGATE, onNavigationStateChange, false, 0, true);
			navItems.push(item);
		}
		
		public function removeNavigatorItem(item : NavigatorItem) : void {
			var l:int = navItems.length;
			for(var i:int = 0; i < l;i++){
				if(navItems[i]==item){
					item.removeEventListener(NavigateEvent.NAVIGATE, onNavigationStateChange);
					navItems.slice(i,1);
				}
			}
		}
		
		public function getNavigatorItemByKey(key:String):NavigatorItem{
			for each(var navitem:NavigatorItem in navItems){
				if(key==navitem.command.name){
					return navitem;
				}
			}
			return null;
		}
		
		public function hasNavigatorItem(item : NavigatorItem) : Boolean {
			var l:int = navItems.length;
			for(var i:int = 0; i < l;i++){
				if(navItems[i]==item) return true;
			}
			return false;
		}
	}
}
